﻿namespace NTLib.Pipe.UTest.Containers
{
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using NTLib.Pipe.Containers;
    using NTLib.Pipe.Descriptors;
    using NTLib.Pipe.Exceptions;
    using NTLib.Pipe.Targets;
    using NTLib.Pipe.UTest.TestData;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;

    [TestClass]
    public class ReadOnlyPipeUTest
    {
        #region Methods

        [TestCategory("Pipe.Containers")]
        [TestMethod]
        public void ReadOnlyPipe_Create()
        {
            using (var pipeSource = new MemoryPipeSource<DataStruct>())
            {
                pipeSource.InitializeAsync(LocalTargetDescription.Instance, PipeType.TwoWay).Wait();
                using (var pipe = new PipeUsingSource<DataStruct>())
                {
                    pipe.SetSource(pipeSource, PipeType.TwoWay);
                    using (ReadOnlyPipe<DataStruct> roPipe = new ReadOnlyPipe<DataStruct>())
                    {
                        //try
                        //{
                        //    roPipe.SendAsync<bool>(null).Wait();
                        //}
                        //catch (PipeActionNotPermitsException)
                        //{

                        //}
                        //catch (Exception ex)
                        //{
                        //    Assert.IsInstanceOfType(ex.InnerException, typeof(PipeActionNotPermitsException));
                        //}

                        try
                        {
                            roPipe.SendAsync(null).Wait();
                        }
                        catch (PipeActionNotPermitsException)
                        {

                        }
                        catch (Exception ex)
                        {
                            Assert.Fail(ex.Message);
                        }

                        roPipe.SetPipe(pipe);

                        Assert.AreEqual(pipe.Id, roPipe.Id);

                        //try
                        //{
                        //    roPipe.PushAsync<bool>(null).Wait();
                        //}
                        //catch (PipeActionNotPermitsException)
                        //{

                        //}
                        //catch (Exception ex)
                        //{
                        //    Assert.IsInstanceOfType(ex.InnerException, typeof(PipeActionNotPermitsException));
                        //}

                        try
                        {
                            roPipe.SendAsync(null).Wait();
                        }
                        catch (PipeActionNotPermitsException)
                        {

                        }
                        catch (Exception ex)
                        {
                            Assert.IsInstanceOfType(ex.InnerException, typeof(PipeActionNotPermitsException));
                        }

                        Assert.AreEqual(roPipe.PipeType, PipeType.FromTarget);
                    }
                }
            }
        }

        [TestCategory("Pipe.Containers")]
        [TestMethod]
        public void ReadOnlyPipe_ReadInfo()
        {
            using (var pipeSource = new MemoryPipeSource<DataStruct>())
            {
                pipeSource.InitializeAsync(LocalTargetDescription.Instance, PipeType.TwoWay).Wait();
                using (var pipe = new PipeUsingSource<DataStruct>())
                {
                    pipe.SetSource(pipeSource, PipeType.TwoWay);
                    using (ReadOnlyPipe<DataStruct> roPipe = new ReadOnlyPipe<DataStruct>())
                    {
                        roPipe.SetPipe(pipe);

                        Guid g = Guid.NewGuid();
                        DataStruct testData = new DataStruct();
                        testData.Data = g.ToString();

                        pipe.SendAsync(testData).Wait();

                        var taskRO = roPipe.PopAsync();
                        taskRO.Wait();

                        Assert.AreNotEqual(taskRO.Result, null);
                        Assert.AreEqual(taskRO.Result.Data, testData.Data);
                    }
                }
            }
        }

        #endregion
    }
}
